----------------------------------------------------------------
-- Global Variables
----------------------------------------------------------------

CharacterSelectWindow = {}

CharacterSelectWindow.NUM_CHARACTER_SLOTS = 10

CharacterSelectWindow.FADE_IN_TIME = 2

CharacterSelectWindow.iState = -1

CharacterSelectWindow.iQueueTime = 0
CharacterSelectWindow.iQueuePos = 0
CharacterSelectWindow.iQueueSize = 0
CharacterSelectWindow.iLastUpdate = 0
CharacterSelectWindow.iMaxQueueTime = 65535 -- the max server time (0xFFFF) is sent down when the server doesn't know what time to send so we won't display a time at that time
CharacterSelectWindow.iCharacterSelection = 0
CharacterSelectWindow.iRealm = -1
CharacterSelectWindow.iRaceChoice = -1
CharacterSelectWindow.iCareerChoice = -1
CharacterSelectWindow.iMouseOver = -1
CharacterSelectWindow.iRealmOver = -1
CharacterSelectWindow.iGender = -1
CharacterSelectWindow.bUseTemplate = false
CharacterSelectWindow.iNumFeatures = 0
CharacterSelectWindow.bMustUseATemplate = false
CharacterSelectWindow.bFirstCharUpdate = false -- this is used to decide if we need to go to the character create screen or the character select screen
CharacterSelectWindow.bAllowTemplatesInPublicBuilds = false

----------------------------------------------------------------
-- Local Variables
----------------------------------------------------------------

CharacterDataOrderCareers = {} -- clear the array
CharacterDataDestructionCareers = {} -- clear the array

local featureStrings = {}    

local REALM_LIMIT_ORDER_ONLY = 2
local REALM_LIMIT_DESTRUCTION_ONLY = 3

local RACE_DWARF = 1
local RACE_EMPIRE = 2
local RACE_HIGH_ELF = 3
local RACE_ORC = 4
local RACE_GOBLIN = 5
local RACE_CHAOS_1 = 6
local RACE_CHAOS_2 = 7
local RACE_DARK_ELF = 8

local CAREER_IRON_BREAKER = 1
local CAREER_SLAYER = 2
local CAREER_ENGINEER = 3
local CAREER_RUNE_PRIEST = 4
local CAREER_BRIGHT_WIZARD = 1
local CAREER_WARRIOR_PRIEST = 2
local CAREER_KNIGHT = 3
local CAREER_WITCH_HUNTER = 4
local CAREER_SWORDMASTER = 1
local CAREER_SHADOW_WARRIOR = 2
local CAREER_WHITE_LION = 3
local CAREER_ARCHMAGE = 4

local CAREER_BLACK_ORC = 1
local CAREER_CHOPPA = 2
local CAREER_SHAMAN = 3
local CAREER_SQUIG_HERDER = 4
local CAREER_ZEALOT = 1
local CAREER_CHOSEN = 2
local CAREER_MAGUS = 3
local CAREER_MARAUDER = 4
local CAREER_BLACKGUARD = 1
local CAREER_WITCH_ELF = 2
local CAREER_DISCIPLE = 3
local CAREER_SORCERER = 4

CharacterSelectWindow.trialPlayer = false
CharacterSelectWindow.buddiedPlayer = false

CharacterSelectWindow.noTransferMessageServers = {L"Jason", L"Int Test [1.2.0]", L"Phoenix Throne"}

----------------------------------------------------------------
-- Constants
----------------------------------------------------------------
local STATE_CHARACTER_LOGIN = 0
local STATE_CHARACTER_SERVER_SELECT = 1
local STATE_CHARACTER_QUICK_ENTRY = 2
local STATE_CHARACTER_SELECT = 3
local STATE_CHARACTER_CREATE_ARMY = 4
local STATE_CHARACTER_CREATE_CAREER = 5
local STATE_CHARACTER_CREATE_FEATURE_IN = 6
local STATE_CHARACTER_CREATE_FEATURE_OUT = 7

local MAX_FEATURES = 8

----------------------------------------------------------------
-- CharacterSelectWindow Functions
----------------------------------------------------------------
function NewCareer( mName, fName, id, desc, maleIma, femaleIma )
    return { MaleName = mName, FemaleName = fName, Id = id, Desc = desc, MaleImage=maleIma, FemaleImage=femaleIma }
end

-- OnInitialize Handler
function CharacterSelectWindow.Initialize()
    --TextLogSetIncrementalSaving( "UiLog", true, L"logs/uilog.log");
    --TextLogSetEnabled( "UiLog", true )
    --WindowSetShowing("DebugWindow", true)

    -- hide the login progress window and clear it
    CharacterSelectWindow.ManageProgressWindow()

    -- Register for the 'CHARACTER_LIST_UDPATED' event
    --WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_LIST_UDPATED, "CharacterSelectWindow.UpdateCharacterList")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_STATE_UPDATED, "CharacterSelectWindow.ForceUpdateState")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_QUEUE_UPDATED, "CharacterSelectWindow.OnQueueUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_CHARACTER_SELECTION_UPDATED, "CharacterSelectWindow.CharacterSelectionUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_CREATE_RACE_UPDATED, "CharacterSelectWindow.RaceUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_CREATE_CAREER_UPDATED, "CharacterSelectWindow.CareerUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_REALM_UPDATED, "CharacterSelectWindow.RealmUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_CREATE_GENDER_UPDATED, "CharacterSelectWindow.GenderUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_MOUSE_OVER_UPDATED, "CharacterSelectWindow.MouseOverUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_REALM_OVER_UPDATED, "CharacterSelectWindow.RealmOverUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_CREATE_NUM_FEATURES_UPDATED, "CharacterSelectWindow.NumFeaturesUpdated")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_TEMPLATES_UPDATED, "CharacterSelectWindow.UpdateCharacterTemplatesList")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_PREGAME_RANDOM_NAME_UPDATE_CHAR_SELECT, "CharacterSelectWindow.UpdateCharacterSelectRandomName")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_PREGAME_RANDOM_NAME_UPDATE_FORCED_SELECT, "CharacterSelectWindow.UpdateCharacterForcedRandomName")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_PREGAME_FORCED_RANDOM_NAME_START, "CharacterSelectWindow.ShowForcedNameSelectWindow")
    WindowRegisterEventHandler( "CharacterSelectWindow", SystemData.Events.CHARACTER_PREGAME_FORCED_RANDOM_NAME_FAILED, "CharacterSelectWindow.ShowForcedRenameFailedWindow")
    
    -- Initial Update
    --CharacterSelectWindow.UpdateCharacterList()
    
    -- Button Text
    ButtonSetText("CharacterSelectServer", GetPregameString( StringTables.Pregame.LABEL_SERVER ) )
    ButtonSetText("CharacterSelectPlay", GetPregameString( StringTables.Pregame.LABEL_PLAY ) )
    ButtonSetText("CharacterSelectNewChar", GetPregameString( StringTables.Pregame.LABEL_CREATE_CHAR ) )
    ButtonSetText("CharacterSelectQuit", GetPregameString( StringTables.Pregame.LABEL_QUIT ) )
    ButtonSetText("CharacterSelectDeleteButton", GetPregameString( StringTables.Pregame.LABEL_DELETE ) )
    ButtonSetText("CharacterSelectUpgradeTrial", GetPregameString( StringTables.Pregame.LABEL_UPGRADE ) )

    ButtonSetText("CharacterSelectBack", GetPregameString( StringTables.Pregame.LABEL_BACK ) )
    ButtonSetText("CharacterSelectCareerToFeature", GetPregameString( StringTables.Pregame.LABEL_NEXT ) )
    ButtonSetText("CharacterSelectCareerCreateChar", GetPregameString( StringTables.Pregame.LABEL_DONE ) )

    LabelSetText("CharacterSelectNameLabel", GetPregameString( StringTables.Pregame.LABEL_NAME ) )
    ButtonSetText("CharacterSelectRandomName", GetPregameString( StringTables.Pregame.LABEL_BUTTON_RANDOM_NAME ) )
    ButtonSetText("CharacterSelectRandomFeatures", GetPregameString( StringTables.Pregame.LABEL_RANDOM ) )

    ButtonSetText("CharacterSelectSettingsButton", GetPregameString( StringTables.Pregame.LABEL_USER_SETTINGS ) )
    ButtonSetText("CharacterSelectUiModButton", GetPregameString( StringTables.Pregame.LABEL_UI_MODS ) )
    WindowSetShowing("CharacterSelectUiModButton", IsInternalBuild() ) -- Hide for public builds atm
    WindowSetShowing("CharacterSelectWindowTemplateCombo", IsInternalBuild() ) -- Hide for public builds atm
    
    WindowSetShowing("CharacterSelectCharacterSlotsAvailableText", false)

    CharacterSelectWindow.InitDeleteDialog()
    CharacterSelectWindow.InitForcedRandomNameDialog()
    CharacterSelectWindow.InitForcedRenameFailedWindow()

    -- set the realm bonus icons
    DynamicImageSetTextureSlice( "CharacterSelectInfoBoxLeftIconBase", "RealmBonus-Order" )
    DynamicImageSetTextureSlice( "CharacterSelectInfoBoxRightIconBase", "RealmBonus-Destruction" )

    -- the careers are set to valid on the server now so there is only the one set of careers
    CharacterSelectWindow.InitializeCharacterDataCareers()

    CharacterSelectWindow.iState = -1
    CharacterSelectWindow.bFirstCharUpdate = true
    
    WindowSetShowing("QueueStatusWindow", false)
    ButtonSetStayDownFlag("CharacterSelectPlay", true )
    CharacterSelectWindow.ResetPlayButton()
    
    CharacterSelectWindow.InitializeFeatureStrings()

    CharacterSelectWindow.ColorizeInfoBoxes(CharacterSelectWindow.iMouseOver)
    WindowSetAlpha("CharacterSelectInfoBoxRightBackgroundBackground", .5)
    WindowSetAlpha("CharacterSelectInfoBoxLeftBackgroundBackground", .5)
    WindowSetAlpha("CharacterSelectInfoBox2RightBackgroundBackground", .5)
    ButtonSetTextColor( "CharacterSelectNewChar", Button.ButtonState.DISABLED, DefaultColor.MEDIUM_GRAY.r, DefaultColor.MEDIUM_GRAY.g, DefaultColor.MEDIUM_GRAY.b)

    LabelSetText("CharacterSelectAutoLoggedText", GetStringFormatFromTable("Pregame", StringTables.Pregame.LABEL_AUTO_LOGGED_IN, {GameData.Account.ServerName}) )
    WindowSetAlpha("CharacterSelectAutoLoggedBackgroundBackground", .75)

    -- Fade the window in
    WindowStartAlphaAnimation( "CharacterSelectWindow", Window.AnimationType.SINGLE, 0.0, 1.0, CharacterSelectWindow.FADE_IN_TIME, false, 0, 0)

    -- update the server name label if the LobbyBackground window exists
    if (DoesWindowExist("LobbyBackground")) then
        LobbyBackground.UpdateServerName()
    end

    -- initialize the mouse over block state
    CharacterSelectWindow.BlockMouseOver(false)

    -- get the player data, this indicates if the player is a trial player and/or a buddied trial player
    CharacterSelectWindow.RefreshPlayerData()
    -- show the upgrade button if this is a trial player
    if CharacterSelectWindow.trialPlayer
    then
        WindowSetShowing("CharacterSelectUpgradeTrial", true)
    else
        WindowSetShowing("CharacterSelectUpgradeTrial", false)
    end

    -- if the transfer flag hasn't been used yet
    if not SystemData.Server.TransferFlagUsed
    then
        -- set the use flag
        SystemData.Server.TransferFlagUsed = true

        local allowTransferMessage = true

        for _, name in ipairs(CharacterSelectWindow.noTransferMessageServers)
        do
            if (name == SystemData.Server.Name)
            then
                allowTransferMessage = false
                break
            end
        end
        
        -- if the transfer flag is on and the server isn't set to not show the transfer message
        if( (SystemData.Server.TransferFlag == 1) and allowTransferMessage )
        then
        
            local serverStatus = EA_Window_TransferPopup.OPEN_SERVER
            local serverInfo = InterfaceCore.GetServerInfo( SystemData.Server.ID )
            if( serverInfo and serverInfo.legacy)
            then
                serverStatus = EA_Window_TransferPopup.LEGACY_SERVER
            end
    
            -- just in case the window doesn't exist
            if (DoesWindowExist("EA_Window_Transfer")) then
                EA_Window_TransferPopup.UpdateServerText( serverStatus )
                EA_Window_TransferPopup.Show()
            end
        end
    end
end

-- OnShutdown Handler
function CharacterSelectWindow.Shutdown()
end

function CharacterSelectWindow.Update( elapsedTime )

    --CharacterSelectWindow.UpdateCameraNodeInfo()
    if CharacterSelectWindow.GetNumSlotsLeft( ) == 0 then
        ButtonSetDisabledFlag( "CharacterSelectNewChar", true )
    else
        ButtonSetDisabledFlag( "CharacterSelectNewChar", false )
    end
    
    CharacterSelectWindow.UpdateName()
    CharacterSelectWindow.UpdateDeleteConfirmation()

    -- Don't drop below 1 second left, and stop counting at that point.
    if (CharacterSelectWindow.iQueueTime > 0.8) then

        CharacterSelectWindow.iQueueTime = CharacterSelectWindow.iQueueTime - elapsedTime
        
        if (CharacterSelectWindow.iQueueTime <= 0.8) then
            CharacterSelectWindow.iQueueTime = 0.8
        end
        
        local currentSec = math.floor( CharacterSelectWindow.iQueueTime )
        
        -- Only update the display when the seconds value has changed since our last display update
        if (CharacterSelectWindow.iLastUpdate ~= currentSec) then
            CharacterSelectWindow.iLastUpdate = currentSec
            CharacterSelectWindow.UpdateQueueStatus()
        end
    end
end

-- Updates all of the Character Data
function CharacterSelectWindow.UpdateCharacterList()

    -- Select the current slot if it is not empty
    if( GameData.Account.CharacterSlot[ GameData.Account.SelectedCharacterSlot ].Name ~= L"" ) then
         CharacterSelectWindow.SelectCharacterSlot( GameData.Account.SelectedCharacterSlot )
    else		
        -- Otherwise select the first slot with a character in it
        for slot = 1, CharacterSelectWindow.NUM_CHARACTER_SLOTS do
            if( GameData.Account.CharacterSlot[ slot ].Name ~= L"" ) then
                 CharacterSelectWindow.SelectCharacterSlot( slot )
                 break
            end
        end
    
        -- If there are now slots that contain a character, ensure our text is cleared
        if( GameData.Account.CharacterSlot[ GameData.Account.SelectedCharacterSlot ].Name == L"" ) then			
            ButtonSetDisabledFlag( "CharacterSelectDeleteButton", true )
            CharacterSelectWindow.NewChar()
        end
    end
end

function CharacterSelectWindow.SelectCharacterSlot( slot )

    GameData.Account.SelectedCharacterSlot = slot

    -- Broadcast the Selection Update
    BroadcastEvent( SystemData.Events.SELECT_CHARACTER )    
    
    if( GameData.Account.SelectedCharacterSlot == 0 ) then  
        ButtonSetDisabledFlag( "CharacterSelectDeleteButton", true )
        return
    end
    
    if( GameData.Account.CharacterSlot[slot].Name ~= L"" ) then
    
        --WindowSetShowing( "CharacterSelectDeleteButton", true )
    
        ButtonSetDisabledFlag( "CharacterSelectDeleteButton", false )
    else
    
        --WindowSetShowing( "CharacterSelectDeleteButton", false )        
    
    
        ButtonSetDisabledFlag( "CharacterSelectDeleteButton", true )
    
        BroadcastEvent( SystemData.Events.BEGIN_CREATE_CHARACTER )          
        
    end
    
end


-- OnLButtonUp Handler for the 'Character00' Buttons
function CharacterSelectWindow.SelectCharacter()
    
    CharacterSelectWindow.SelectCharacterSlot( WindowGetId(SystemData.ActiveWindow.name) )
end

function CharacterSelectWindow.ResetPlayButton()

    ButtonSetPressedFlag("CharacterSelectPlay", false )
    ButtonSetDisabledFlag("CharacterSelectPlay", false )

end


-- OnLButtonUp Handler for the 'Play' Button
function CharacterSelectWindow.Play( flags, mouseX, mouseY )

    if (ButtonGetDisabledFlag("CharacterSelectPlay"))
    then
        return
    end

    if STATE_CHARACTER_SELECT ~= CharacterSelectWindow.iState
    then
        return
    end

    -- Ensure the player has selected a valid slot  
    --[[
    if( GameData.Account.CharacterSlot[ GameData.Account.SelectedCharacterSlot ].Name == L"" ) then     
        local text = GetPregameString( StringTables.Pregame.NEED_SELECT_CHARACTER_TEXT )
        local btnText = GetPregameString( StringTables.Pregame.LABEL_OKAY )
        DialogManager.MakeOneButtonDialog( text, btnText )
        return  
    end
    --]]

    DataUtils.BeginLoading()
    ButtonSetDisabledFlag("CharacterSelectPlay", true)
    BroadcastEvent( SystemData.Events.PLAY)

    
end

function CharacterSelectWindow.NewChar()
    if (ButtonGetDisabledFlag( "CharacterSelectNewChar" ) == true) then
        return
    end
    
    -- Close Any Secondary Windows that may be up
    
    local function CloseIfShowing( windowName, closeFunction )
        if( WindowGetShowing( windowName ) )
        then
            closeFunction()
        end
    end
    
    CloseIfShowing( "SettingsWindowTabbed",         SettingsWindowTabbed.OnCancelButton )
    CloseIfShowing( "UiModAdvancedWindow",          UiModWindow.OnAdvancedCancelButton )
    CloseIfShowing( "EA_Window_CinematicDisplay",   PregameCloseCinematicWindow )
    CloseIfShowing( "EA_Window_Credits",            EA_Window_Credits.Hide )

    
    GameData.Account.SelectedCharacterSlot = -1
    -- Broadcast the Selection Update
    BroadcastEvent( SystemData.Events.SELECT_CHARACTER )    
    BroadcastEvent( SystemData.Events.BEGIN_CREATE_CHARACTER )
    CharacterSelectWindow.ChangeState(STATE_CHARACTER_CREATE_ARMY)
end

function CharacterSelectWindow.ShowAvailableSlots()
    LabelSetText("CharacterSelectCharacterSlotsAvailableText", GetStringFormatFromTable("Pregame", StringTables.Pregame.LABEL_CHARACTER_SLOTS_AVAILABLE, {CharacterSelectWindow.GetNumSlotsLeftText()})) 
    WindowSetShowing("CharacterSelectCharacterSlotsAvailableText", true)
end

function CharacterSelectWindow.HideAvailableSlots()
    WindowSetShowing("CharacterSelectCharacterSlotsAvailableText", false)
end

-- OnLButtonUp Handler for the 'Quit' Button
function CharacterSelectWindow.Quit( flags, mouseX, mouseY )

    -- Broadcast the event
    BroadcastEvent( SystemData.Events.QUIT )
end

function CharacterSelectWindow.BlockMouseOver(bBlock)
    -- start/stop handling mouse over & mouse button clicks on the C side
    PregameBlockMouseOver(bBlock)
end

function CharacterSelectWindow.InitDeleteDialog()
    local deleteLabel = GetPregameString( StringTables.Pregame.LABEL_DELETE )
    local cancelLabel = GetPregameString( StringTables.Pregame.LABEL_CANCEL )
    local promptLabel = GetPregameString( StringTables.Pregame.LABEL_TYPE_Y_E_S )
    WindowSetShowing("DeleteConfirmation", false)
    ButtonSetText("DeleteConfirmationBoxDelete", deleteLabel )
    ButtonSetText("DeleteConfirmationBoxCancel", cancelLabel )
    LabelSetText( "DeleteConfirmationBoxLabelPrompt", promptLabel )
end

function CharacterSelectWindow.UpdateDeleteConfirmation( )
    -- if we aren't showing the delete confirmation window then we don't need to update the edit box
    if not WindowGetShowing("DeleteConfirmation") then
        return
    end

    -- if the edit box has any text in it
    if (DeleteConfirmationBoxEdit.Text ~= L"") then
        -- make it upper case
        local wszUpper = wstring.upper( DeleteConfirmationBoxEdit.Text )
        -- set the upper case text to the text box
        TextEditBoxSetText("DeleteConfirmationBoxEdit", wszUpper ) 
        -- check to see if we have spelled yes yet
        if (DeleteConfirmationBoxEdit.Text == GetPregameString( StringTables.Pregame.LABEL_CAPITAL_YES )) then
            -- enable the delete button if we have
            ButtonSetDisabledFlag("DeleteConfirmationBoxDelete", false)
        -- otherwise disable it, this is to assure if they type yes and backspace it disables the delete button
        else
            ButtonSetDisabledFlag("DeleteConfirmationBoxDelete", true)
        end
    -- if there is no text in the box we also want to make sure the delete button is disabled
    else
        ButtonSetDisabledFlag("DeleteConfirmationBoxDelete", true)
    end
end

function CharacterSelectWindow.HideDeleteDialog()
    WindowSetShowing("DeleteConfirmation", false)

    -- this allows the player to change characters again after the cancel button is hit
    CharacterSelectWindow.BlockMouseOver(false)
end

-- OnLButtonUp Handler for the 'Delete' Button
function CharacterSelectWindow.Delete( flags, mouseX, mouseY )

    if( GameData.Account.CharacterSlot[ GameData.Account.SelectedCharacterSlot ].Name == L"" ) then
        return
    end

    -- this stops the player from changing the selected character during the deletion process.
    CharacterSelectWindow.BlockMouseOver(true)

    -- Create a Confirmation Dialog
    local charName = GameData.Account.CharacterSlot[ GameData.Account.SelectedCharacterSlot ].Name
    local text = GetPregameStringFormat( StringTables.Pregame.TEXT_DELETE_CONFIRM, { charName } )

    LabelSetText( "DeleteConfirmationBoxLabelDialog", text )
    ButtonSetDisabledFlag("DeleteConfirmationBoxDelete", true)
    WindowSetShowing("DeleteConfirmation", true)
    -- assure that the edit box retains has focus
    CharacterSelectWindow.GiveDeleteEditBoxFocus()
    -- initialize the edit box to be empty
    TextEditBoxSetText("DeleteConfirmationBoxEdit", L"" )
end

function CharacterSelectWindow.DoDelete()
    -- if the player hasn't typed in "YES" then we don't want to delete the character yet
    if (ButtonGetDisabledFlag( "DeleteConfirmationBoxDelete" ) == true) then
        return
    end

    -- Broadcast the event
    BroadcastEvent( SystemData.Events.DELETE_CHARACTER )
    WindowSetShowing("DeleteConfirmation", false)

    -- this allows the player to change characters again after the delete button is hit
    CharacterSelectWindow.BlockMouseOver(false)
end

function CharacterSelectWindow.OnSettingsButton()
    -- Open the Settings Window
    local showing = WindowGetShowing("SettingsWindowTabbed" )
    WindowSetShowing("SettingsWindowTabbed", not showing  )        
end

function CharacterSelectWindow.OnUiModButton()

    -- Open the Ui Mod Advanced Settings Window
    local showing = WindowGetShowing("UiModAdvancedWindow" )
    WindowSetShowing("UiModAdvancedWindow", not showing  )        
end

function CharacterSelectWindow.LButtonUp( flags, mouseX, mouseY )
    -- Broadcast the event
    BroadcastEvent( SystemData.Events.MOUSE_UP_ON_CHAR_SELECT_NIF )
end

function CharacterSelectWindow.LButtonDown( flags, mouseX, mouseY )
    -- Broadcast the event
    BroadcastEvent( SystemData.Events.MOUSE_DOWN_ON_CHAR_SELECT_NIF )
end

function CharacterSelectWindow.ClearMouseOverText( )
    LabelSetText( "CharacterSelectMouseOverLabel", L"" )
end

function CharacterSelectWindow.GetNumSlotsLeftText( )
    return L""..CharacterSelectWindow.GetNumSlotsLeft( )
end

function CharacterSelectWindow.GetNumSlotsLeft( )
    local slotCount = 0
    for slot = 1, CharacterSelectWindow.NUM_CHARACTER_SLOTS do
        if( GameData.Account.CharacterSlot[ slot ].Name == L"" ) then
            slotCount = slotCount + 1
        end
    end

    return slotCount
end

function CharacterSelectWindow.InitializeCharacterDataCareers()
    CharacterDataOrderCareers = {} -- clear the array
    CharacterDataDestructionCareers = {} -- clear the array
    -- Dwarf
    CharacterDataOrderCareers[ 1 ] = {}
    CharacterDataOrderCareers[ 1 ].Id = 1
    CharacterDataOrderCareers[ 1 ].Name = GetPregameString( StringTables.Pregame.RACE_DWARF )
    CharacterDataOrderCareers[ 1 ].Desc = GetPregameString( StringTables.Pregame.RACE_DWARF_DESC )
    CharacterDataOrderCareers[ 1 ].ArmyScreenCareerChoice = 1
    CharacterDataOrderCareers[ 1 ].ArmyScreenCareerGenderChoice = 1	-- male
    CharacterDataOrderCareers[ 1 ].Genders = {}
    CharacterDataOrderCareers[ 1 ].Careers = {}
    CharacterDataOrderCareers[ 1 ].Careers[ 1 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.IRON_BREAKER ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.IRON_BREAKER ), 20, GetPregameString( StringTables.Pregame.CAREER_IRON_BREAKER_DESC ), 16, 17 )
    CharacterDataOrderCareers[ 1 ].Careers[ 2 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.SLAYER ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.SLAYER ), 21, GetPregameString( StringTables.Pregame.CAREER_SLAYER_DESC ), 18, nil )
    CharacterDataOrderCareers[ 1 ].Careers[ 3 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.ENGINEER ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.ENGINEER ), 23, GetPregameString( StringTables.Pregame.CAREER_ENGINEER_DESC ), 20, 21 )
    CharacterDataOrderCareers[ 1 ].Careers[ 4 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.RUNE_PRIEST ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.RUNE_PRIEST ), 22, GetPregameString( StringTables.Pregame.CAREER_RUNE_PRIEST_DESC ), 22, 23 )
    -- Empire
    CharacterDataOrderCareers[ 2 ] = {}
    CharacterDataOrderCareers[ 2 ].Id = 6
    CharacterDataOrderCareers[ 2 ].Name = GetPregameString( StringTables.Pregame.RACE_EMPIRE )
    CharacterDataOrderCareers[ 2 ].Desc = GetPregameString( StringTables.Pregame.RACE_EMPIRE_DESC )
    CharacterDataOrderCareers[ 2 ].ArmyScreenCareerChoice = 1
    CharacterDataOrderCareers[ 2 ].ArmyScreenCareerGenderChoice = 1	-- male
    CharacterDataOrderCareers[ 2 ].Genders = {}
    CharacterDataOrderCareers[ 2 ].Careers = {}
    CharacterDataOrderCareers[ 2 ].Careers[ 1 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.BRIGHT_WIZARD ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.BRIGHT_WIZARD ), 62, GetPregameString( StringTables.Pregame.CAREER_BRIGHT_WIZARD_DESC ), 32, 33 )
    CharacterDataOrderCareers[ 2 ].Careers[ 2 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.WARRIOR_PRIEST ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.WARRIOR_PRIEST ), 63, GetPregameString( StringTables.Pregame.CAREER_WARRIOR_PRIEST_DESC ), 36, 37 )
    CharacterDataOrderCareers[ 2 ].Careers[ 3 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.KNIGHT ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.KNIGHT ), 61, GetPregameString( StringTables.Pregame.CAREER_KNIGHT_DESC ), 30, 31 )
    CharacterDataOrderCareers[ 2 ].Careers[ 4 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.WITCH_HUNTER ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.WITCH_HUNTER ), 60, GetPregameString( StringTables.Pregame.CAREER_WITCH_HUNTER_DESC ), 34, 35 )
    -- High Elf
    CharacterDataOrderCareers[ 3 ] = {}
    CharacterDataOrderCareers[ 3 ].Id = 4
    CharacterDataOrderCareers[ 3 ].Name = GetPregameString( StringTables.Pregame.RACE_ELVES )
    CharacterDataOrderCareers[ 3 ].Desc = GetPregameString( StringTables.Pregame.RACE_ELVES_DESC )
    CharacterDataOrderCareers[ 3 ].ArmyScreenCareerChoice = 2
    CharacterDataOrderCareers[ 3 ].ArmyScreenCareerGenderChoice = 2	-- female
    CharacterDataOrderCareers[ 3 ].Genders = {}
    CharacterDataOrderCareers[ 3 ].Careers = {}
    CharacterDataOrderCareers[ 3 ].Careers[ 1 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.SWORDMASTER ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.SWORDMASTER ), 100, GetPregameString( StringTables.Pregame.CAREER_SWORDMASTER_DESC ), 48, 49 )
    CharacterDataOrderCareers[ 3 ].Careers[ 2 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.SHADOW_WARRIOR ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.SHADOW_WARRIOR ), 101, GetPregameString( StringTables.Pregame.CAREER_SHADOW_WARRIOR_DESC ), 50, 51 )
    CharacterDataOrderCareers[ 3 ].Careers[ 3 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.SEER ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.SEER ), 102, GetPregameString( StringTables.Pregame.CAREER_SEER_DESC ), 46, 47 )
    CharacterDataOrderCareers[ 3 ].Careers[ 4 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.ARCHMAGE ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.ARCHMAGE ), 103, GetPregameString( StringTables.Pregame.CAREER_ARCH_MAGE_DESC ), 44, 45 )
    
    -- Destruction
    -- Greenskin
    CharacterDataDestructionCareers[ 1 ] = {}
    CharacterDataDestructionCareers[ 1 ].Id = 2
    CharacterDataDestructionCareers[ 1 ].Name = GetPregameString( StringTables.Pregame.RACE_GREENSKIN )
    CharacterDataDestructionCareers[ 1 ].Desc = GetPregameString( StringTables.Pregame.RACE_GREENSKIN_DESC )
    CharacterDataDestructionCareers[ 1 ].ArmyScreenCareerChoice = 3
    CharacterDataDestructionCareers[ 1 ].ArmyScreenCareerGenderChoice = 1	-- male not that it matters
    CharacterDataDestructionCareers[ 1 ].Genders = {}
    CharacterDataDestructionCareers[ 1 ].Careers = {}
    CharacterDataDestructionCareers[ 1 ].Careers[ 1 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.BLACK_ORC ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.BLACK_ORC ), 24, GetPregameString( StringTables.Pregame.CAREER_BLACKORC_DESC ), 12, nil )
    CharacterDataDestructionCareers[ 1 ].Careers[ 2 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.CHOPPA ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.CHOPPA ), 25, GetPregameString( StringTables.Pregame.CAREER_IRON_CLAW_DESC ), 13, nil )
    CharacterDataDestructionCareers[ 1 ].Careers[ 3 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.SHAMAN ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.SHAMAN ), 26, GetPregameString( StringTables.Pregame.CAREER_SHAMAN_DESC ), 14, nil )
    CharacterDataDestructionCareers[ 1 ].Careers[ 4 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.SQUIG_HERDER ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.SQUIG_HERDER ), 27, GetPregameString( StringTables.Pregame.CAREER_SQUIG_HERDER_DESC ), 15, nil )
    -- Chaos
    CharacterDataDestructionCareers[ 2 ] = {}
    CharacterDataDestructionCareers[ 2 ].Id = 7
    CharacterDataDestructionCareers[ 2 ].Name = GetPregameString( StringTables.Pregame.RACE_CHAOS )
    CharacterDataDestructionCareers[ 2 ].Desc = GetPregameString( StringTables.Pregame.RACE_CHAOS_DESC )
    CharacterDataDestructionCareers[ 2 ].ArmyScreenCareerChoice = 2
    CharacterDataDestructionCareers[ 2 ].ArmyScreenCareerGenderChoice = 1	-- male
    CharacterDataDestructionCareers[ 2 ].Genders = {}
    CharacterDataDestructionCareers[ 2 ].Careers = {}
    CharacterDataDestructionCareers[ 2 ].Careers[ 1 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.ZEALOT ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.ZEALOT ), 66, GetPregameString( StringTables.Pregame.CAREER_ZEALOT_DESC ), 26, 27 )
    CharacterDataDestructionCareers[ 2 ].Careers[ 2 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.CHOSEN ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.CHOSEN ), 64, GetPregameString( StringTables.Pregame.CAREER_CHOSEN_DESC ), 24, nil )
    CharacterDataDestructionCareers[ 2 ].Careers[ 3 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.MAGUS ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.MAGUS ), 67, GetPregameString( StringTables.Pregame.CAREER_MAGUS_DESC ), 28, 29 )
    CharacterDataDestructionCareers[ 2 ].Careers[ 4 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.WARRIOR ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.WARRIOR ), 65, GetPregameString( StringTables.Pregame.CAREER_CHAOS_WARRIOR_DESC ), 25, nil )
    -- Dark Elf
    CharacterDataDestructionCareers[ 3 ] = {}
    CharacterDataDestructionCareers[ 3 ].Id = 5
    CharacterDataDestructionCareers[ 3 ].Name = GetPregameString( StringTables.Pregame.RACE_DARK_ELVES )
    CharacterDataDestructionCareers[ 3 ].Desc = GetPregameString( StringTables.Pregame.RACE_DARK_ELVES_DESC )
    CharacterDataDestructionCareers[ 3 ].ArmyScreenCareerChoice = 4
    CharacterDataDestructionCareers[ 3 ].ArmyScreenCareerGenderChoice = 2	-- female
    CharacterDataDestructionCareers[ 3 ].Genders = {}
    CharacterDataDestructionCareers[ 3 ].Careers = {}
    CharacterDataDestructionCareers[ 3 ].Careers[ 1 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.SHADE ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.SHADE ), 104, GetPregameString( StringTables.Pregame.CAREER_SHADE_DESC ), 39, 40 )
    CharacterDataDestructionCareers[ 3 ].Careers[ 2 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.ASSASSIN ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.ASSASSIN ), 105, GetPregameString( StringTables.Pregame.CAREER_ASSASSIN_DESC ), nil, 43 )
    CharacterDataDestructionCareers[ 3 ].Careers[ 3 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.BLOOD_PRIEST ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.BLOOD_PRIEST ), 106, GetPregameString( StringTables.Pregame.CAREER_BLOOD_PRIEST_DESC ), 38, 11  )
    CharacterDataDestructionCareers[ 3 ].Careers[ 4 ] = NewCareer( GetStringFromTable( "CareerLinesMale", GameData.CareerLine.SORCERER ), GetStringFromTable( "CareerLinesFemale", GameData.CareerLine.SORCERER ), 107, GetPregameString( StringTables.Pregame.CAREER_SORCERER_DESC ), 41, 42 )

    CharacterSelectWindow.UpdateCharacterDataLuaVars()
end

function CharacterSelectWindow.UpdateCharacterDataLuaVars()
    for race = 1, 3 do
        if CharacterDataOrderCareers[race] ~= nil then
            if CharacterDataOrderCareers[race].Careers[CharacterDataOrderCareers[ race ].ArmyScreenCareerChoice] ~= nil then
                GameData.Account.CharacterCreation.OrderRaces[race].ArmyName = CharacterDataOrderCareers[race].Name
                GameData.Account.CharacterCreation.OrderRaces[race].Race = CharacterDataOrderCareers[race].Id
                GameData.Account.CharacterCreation.OrderRaces[race].Career = CharacterDataOrderCareers[race].Careers[CharacterDataOrderCareers[ race ].ArmyScreenCareerChoice].Id
                if CharacterDataOrderCareers[race].ArmyScreenCareerGenderChoice == 1 then
                    GameData.Account.CharacterCreation.OrderRaces[race].Image = CharacterDataOrderCareers[race].Careers[CharacterDataOrderCareers[ race ].ArmyScreenCareerChoice].MaleImage
                    GameData.Account.CharacterCreation.OrderRaces[race].Gender = 0 -- male gender is 0 C side
                else
                    GameData.Account.CharacterCreation.OrderRaces[race].Image = CharacterDataOrderCareers[race].Careers[CharacterDataOrderCareers[ race ].ArmyScreenCareerChoice].FemaleImage
                    GameData.Account.CharacterCreation.OrderRaces[race].Gender = 1 -- female gender is 0 C side
                end
            end
            for career = 1, 4 do
                if CharacterDataOrderCareers[race].Careers[career] ~= nil then
                    GameData.Account.CharacterCreation.OrderCareers[race][career].ArmyName = CharacterDataOrderCareers[race].Name
                    GameData.Account.CharacterCreation.OrderCareers[race][career].MaleCareerName = CharacterDataOrderCareers[race].Careers[career].MaleName
                    GameData.Account.CharacterCreation.OrderCareers[race][career].FemaleCareerName = CharacterDataOrderCareers[race].Careers[career].FemaleName
                    GameData.Account.CharacterCreation.OrderCareers[race][career].Race = CharacterDataOrderCareers[race].Id
                    GameData.Account.CharacterCreation.OrderCareers[race][career].Career = CharacterDataOrderCareers[race].Careers[career].Id
                    GameData.Account.CharacterCreation.OrderCareers[race][career].MaleImage = CharacterDataOrderCareers[race].Careers[career].MaleImage
                    GameData.Account.CharacterCreation.OrderCareers[race][career].FemaleImage = CharacterDataOrderCareers[race].Careers[career].FemaleImage
                end
            end
        end
        if CharacterDataDestructionCareers[race] ~= nil then
            if CharacterDataDestructionCareers[race].Careers[CharacterDataDestructionCareers[ race ].ArmyScreenCareerChoice] ~= nil then
                GameData.Account.CharacterCreation.DestructionRaces[race].ArmyName = CharacterDataDestructionCareers[race].Name
                GameData.Account.CharacterCreation.DestructionRaces[race].Race = CharacterDataDestructionCareers[race].Id
                GameData.Account.CharacterCreation.DestructionRaces[race].Career = CharacterDataDestructionCareers[race].Careers[CharacterDataDestructionCareers[ race ].ArmyScreenCareerChoice].Id
                if CharacterDataDestructionCareers[race].ArmyScreenCareerGenderChoice == 1 then
                    GameData.Account.CharacterCreation.DestructionRaces[race].Image = CharacterDataDestructionCareers[race].Careers[CharacterDataDestructionCareers[ race ].ArmyScreenCareerChoice].MaleImage
                    GameData.Account.CharacterCreation.DestructionRaces[race].Gender = 0 -- male gender is 0 C side
                else
                    GameData.Account.CharacterCreation.DestructionRaces[race].Image = CharacterDataDestructionCareers[race].Careers[CharacterDataDestructionCareers[ race ].ArmyScreenCareerChoice].FemaleImage
                    GameData.Account.CharacterCreation.DestructionRaces[race].Gender = 1 -- female gender is 1 C side
                end
            end
            for career = 1, 4 do
                if CharacterDataDestructionCareers[race].Careers[career] ~= nil then
                    GameData.Account.CharacterCreation.DestructionCareers[race][career].ArmyName = CharacterDataDestructionCareers[race].Name
                    GameData.Account.CharacterCreation.DestructionCareers[race][career].MaleCareerName = CharacterDataDestructionCareers[race].Careers[career].MaleName
                    GameData.Account.CharacterCreation.DestructionCareers[race][career].FemaleCareerName = CharacterDataDestructionCareers[race].Careers[career].FemaleName
                    GameData.Account.CharacterCreation.DestructionCareers[race][career].Race = CharacterDataDestructionCareers[race].Id
                    GameData.Account.CharacterCreation.DestructionCareers[race][career].Career = CharacterDataDestructionCareers[race].Careers[career].Id
                    GameData.Account.CharacterCreation.DestructionCareers[race][career].MaleImage = CharacterDataDestructionCareers[race].Careers[career].MaleImage
                    GameData.Account.CharacterCreation.DestructionCareers[race][career].FemaleImage = CharacterDataDestructionCareers[race].Careers[career].FemaleImage
                end
            end
        end
    end
    BroadcastEvent( SystemData.Events.CHARACTER_DATA_LUA_VARS_UPDATED )
end

function CharacterSelectWindow.ShowCharacterSelect(bShow)
    WindowSetShowing("CharacterSelectQuit", bShow)
    WindowSetShowing("CharacterSelectSettingsButton", bShow)
    WindowSetShowing("CharacterSelectDeleteButton", bShow)
    WindowSetShowing("CharacterSelectNewChar", bShow)
    WindowSetShowing("CharacterSelectServer", bShow)
    WindowSetShowing("CharacterSelectPlay", bShow)
end

function CharacterSelectWindow.ShowCharacterCreateArmy(bShow)
    -- if we have no characters we will hide the back button on the army screen
    -- and so that there is an option for the player we will show the server select button
    -- we will also show the server welcome text if there are no characters on the server
    if CharacterSelectWindow.iCharacterSelection == -1 then
        WindowSetShowing("CharacterSelectBack", false)
        WindowSetShowing("CharacterSelectServer", bShow)
        
        -- if we have been auto logged into this server
        if ServerSelectWindow.autoLoggedIn
        then
            -- show the welcome text and hide the server name text or vice versa
            WindowSetShowing("CharacterSelectAutoLogged", bShow)
            WindowSetShowing("LobbyBackgroundServerName", not bShow)
        -- otherwise we will hide the welcome text and show the server name
        else
            WindowSetShowing("CharacterSelectAutoLogged", false)
            WindowSetShowing("LobbyBackgroundServerName", true)
        end
    else
        WindowSetShowing("CharacterSelectBack", bShow)
        -- if there are characters we don't show the server welcome text
        WindowSetShowing("CharacterSelectAutoLogged", false)
        -- but we do want to show the server name
        WindowSetShowing("LobbyBackgroundServerName", true)
    end
    WindowSetShowing("CharacterSelectInfoBoxRight", bShow)
    WindowSetShowing("CharacterSelectInfoBoxLeft", bShow)
end

function CharacterSelectWindow.ShowCharacterCreateCareer(bShow)
    if CharacterSelectWindow.iCareerChoice == -1 then
        WindowSetShowing("CharacterSelectCareerToFeature", false)
    else
        WindowSetShowing("CharacterSelectCareerToFeature", bShow)
    end
    WindowSetShowing("CharacterSelectBack", bShow)
    WindowSetShowing("CharacterSelectInfoBox2Right", bShow)
    CharacterSelectWindow.ShowGenderButtons(bShow)
end

function CharacterSelectWindow.ShowCharacterCreateFeature(bShow)
    WindowSetShowing("CharacterSelectCareerCreateChar", bShow)
    WindowSetShowing("CharacterSelectBack", bShow)

    --DEBUG(L"CharacterSelectWindow.iRealm = "..CharacterSelectWindow.iRealm)
    --DEBUG(L"CharacterSelectWindow.iRaceChoice = "..CharacterSelectWindow.iRaceChoice)
    --DEBUG(L"CharacterSelectWindow.iCareerChoice = "..CharacterSelectWindow.iCareerChoice)
    CharacterSelectWindow.ShowGenderButtons(bShow)
    WindowSetShowing("CharacterSelectNameEdit", bShow)
    if ( bShow ) then
        WindowAssignFocus( "CharacterSelectNameEdit", true )
    end
    WindowSetShowing("CharacterSelectNameEditBackground", bShow)
    WindowSetShowing("CharacterSelectNameLabel", bShow)
    WindowSetShowing("CharacterSelectRandomName", bShow)
    CharacterSelectWindow.SetFeatureLabels(bShow)
    WindowSetShowing("CharacterSelectCareerZoomIn", bShow)
    WindowSetShowing("CharacterSelectCareerZoomOut", bShow)
    
    -- if we must use a template then we want to make sure we show/hide the combo box
    -- we will only use templates with a public build when the AllowPublicTemplates returns true
    -- and if we are an internal build we will want to show/hide it properly
    if (IsInternalBuild() or (CharacterSelectWindow.AllowPublicTemplates() and CharacterSelectWindow.bMustUseATemplate))
    then
        WindowSetShowing("CharacterSelectWindowTemplateCombo", bShow)
    end
end

function CharacterSelectWindow.ShowGenderButtons(bShow)
    if CharacterSelectWindow.iRealm == 2 and CharacterSelectWindow.iRaceChoice == 1 then -- if it is a greenskin we don't show the gender buttons
        WindowSetShowing("CharacterSelectCareerGenderMale", false)
        WindowSetShowing("CharacterSelectCareerGenderFemale", false)
    else
        -- the default state of the gender buttons is enabled
        ButtonSetDisabledFlag("CharacterSelectCareerGenderMale", false)
        ButtonSetDisabledFlag("CharacterSelectCareerGenderFemale", false)
        if ((CharacterSelectWindow.iRaceChoice > 0) and (CharacterSelectWindow.iCareerChoice > 0)) then
            if (1 == CharacterSelectWindow.iRealm and (CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].MaleImage == nil)) then
                ButtonSetDisabledFlag("CharacterSelectCareerGenderMale", true)
            elseif (2 == CharacterSelectWindow.iRealm and (CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].MaleImage == nil)) then
                ButtonSetDisabledFlag("CharacterSelectCareerGenderMale", true)
            end
            if (1 == CharacterSelectWindow.iRealm and (CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].FemaleImage == nil)) then
                ButtonSetDisabledFlag("CharacterSelectCareerGenderFemale", true)
            elseif (2 == CharacterSelectWindow.iRealm and (CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].FemaleImage == nil)) then
                ButtonSetDisabledFlag("CharacterSelectCareerGenderFemale", true)
            end
        end
        WindowSetShowing("CharacterSelectCareerGenderMale", bShow)
        WindowSetShowing("CharacterSelectCareerGenderFemale", bShow)
    end
end

function CharacterSelectWindow.ShowServerSelect()
    --DEBUG(L"SERVER SELECT")
    BroadcastEvent( SystemData.Events.PREGAME_LAUNCH_SERVER_SELECT )
end

function CharacterSelectWindow.Back()
    --DEBUG(L"GOING BACK")
    if CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_FEATURE_IN or CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_FEATURE_OUT then
        CharacterSelectWindow.ChangeState(STATE_CHARACTER_CREATE_CAREER)
    elseif CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_CAREER then
        CharacterSelectWindow.ChangeState(STATE_CHARACTER_CREATE_ARMY)
    elseif CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_ARMY then
        CharacterSelectWindow.ChangeState(STATE_CHARACTER_CREATE_ARMY)
        CharacterSelectWindow.ChangeState(STATE_CHARACTER_SELECT)
    end
    
    --Clear the random name list
    -- initialize the name box to be empty
    TextEditBoxSetText("CharacterSelectNameEdit", L"" )
    BroadcastEvent( SystemData.Events.PREGAME_CLEAR_RANDOM_NAME_LIST )
end

function CharacterSelectWindow.ToCareer()
    --DEBUG(L"ToCareer")
    CharacterSelectWindow.ChangeState(STATE_CHARACTER_CREATE_CAREER)
end

function CharacterSelectWindow.ToFeature()
    --DEBUG(L"ToFeature")
    CharacterSelectWindow.ChangeState(STATE_CHARACTER_CREATE_FEATURE_IN)
end

function CharacterSelectWindow.CreateChar()
    --DEBUG(L"CreateChar")
    -- if the create character button is disabled we will return without doing anything
    if (ButtonGetDisabledFlag( "CharacterSelectCareerCreateChar" ) == true) then
        return
    end
    if (CharacterSelectWindow.bUseTemplate) then
        if( (GameData.Account.CharacterCreation.Gender) == 1 ) then
            if 1 == CharacterSelectWindow.iRealm then
                GameData.Account.CharacterCreation.Image = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].MaleImage
            else
                GameData.Account.CharacterCreation.Image = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].MaleImage
            end
        else
            if 1 == CharacterSelectWindow.iRealm then
                GameData.Account.CharacterCreation.Image = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].FemaleImage
            else
                GameData.Account.CharacterCreation.Image = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].FemaleImage
            end
        end
    end

    BroadcastEvent( SystemData.Events.CREATE_CHARACTER )
end

function CharacterSelectWindow.ChangeState(iState)
    CharacterSelectWindow.ForceUpdateState(iState)
    BroadcastEvent( SystemData.Events.PREGAME_SET_STATE )
end

function CharacterSelectWindow.RandomName()
    if( ButtonGetDisabledFlag( "CharacterSelectRandomName" ) ) then
        return
    end
    ButtonSetDisabledFlag("CharacterSelectRandomName", true)
    BroadcastEvent( SystemData.Events.CHARACTER_PREGAME_RANDOM_NAME_REQUESTED )
end

function CharacterSelectWindow.ForcedRandomName()
    if( ButtonGetDisabledFlag( "ForcedRandomNameBoxRandom" ) ) then
        return
    end
    ButtonSetDisabledFlag("ForcedRandomNameBoxRandom", true)
    BroadcastEvent( SystemData.Events.CHARACTER_PREGAME_RANDOM_NAME_REQUESTED )
end

function CharacterSelectWindow.NextFeature()
    GameData.Account.CharacterCreation.ActiveFeature = WindowGetId(WindowGetParent(SystemData.ActiveWindow.name)) - 1 -- subtract 1 because of the lua indexing by 1 and c indexing by 0
    --DEBUG(L"NextFeature: GameData.Account.CharacterCreation.ActiveFeature = "..GameData.Account.CharacterCreation.ActiveFeature)
    BroadcastEvent( SystemData.Events.NEXT_FEATURE )
end

function CharacterSelectWindow.PrevFeature()
    GameData.Account.CharacterCreation.ActiveFeature = WindowGetId(WindowGetParent(SystemData.ActiveWindow.name)) - 1 -- subtract 1 because of the lua indexing by 1 and c indexing by 0
    --DEBUG(L"PrevFeature: GameData.Account.CharacterCreation.ActiveFeature = "..GameData.Account.CharacterCreation.ActiveFeature)
    BroadcastEvent( SystemData.Events.PREV_FEATURE )
end

function CharacterSelectWindow.GetFeatureLabel(iFeature)
    local iRaceChoice = CharacterSelectWindow.iRaceChoice

    if 1 == CharacterSelectWindow.iRealm
    then
        iRaceChoice = CharacterSelectWindow.iRaceChoice -- order races are nice to deal with
    else
        -- not so much with the destruction races
        if 3 == CharacterSelectWindow.iRaceChoice
        then
            iRaceChoice = RACE_DARK_ELF
        elseif 2 == CharacterSelectWindow.iRaceChoice
        then
            if ((CAREER_ZEALOT == CharacterSelectWindow.iCareerChoice) or (CAREER_MAGUS == CharacterSelectWindow.iCareerChoice)) then
                iRaceChoice = RACE_CHAOS_1
            else
                iRaceChoice = RACE_CHAOS_2
            end
        else
            if ((CAREER_BLACK_ORC == CharacterSelectWindow.iCareerChoice) or (CAREER_CHOPPA == CharacterSelectWindow.iCareerChoice)) then
                iRaceChoice = RACE_ORC
            else
                iRaceChoice = RACE_GOBLIN
            end
        end
    end

    if 1 == CharacterSelectWindow.iGender
    then -- male
        return featureStrings[ iRaceChoice ].Career[CharacterSelectWindow.iCareerChoice].FeatureNameMale[iFeature]
    else -- female
        return featureStrings[ iRaceChoice ].Career[CharacterSelectWindow.iCareerChoice].FeatureNameFemale[iFeature]
    end
end

function CharacterSelectWindow.SetFeatureLabels(bShow)
    -- DEBUG(L"CharacterSelectWindow.SetFeatureLabels()")
    iNumFeatures = CharacterSelectWindow.iNumFeatures

    for iIndex = 1, MAX_FEATURES
    do
        if (iIndex < iNumFeatures+1)
        then
            if ((CharacterSelectWindow.iRaceChoice > 0) and (CharacterSelectWindow.iCareerChoice > 0))
            then
                LabelSetText("CharacterSelectFeatureWindow"..iIndex.."FeatureLabel", CharacterSelectWindow.GetFeatureLabel(iIndex))
            else
                LabelSetText("CharacterSelectFeatureWindow"..iIndex.."FeatureLabel", L"Feature "..iIndex..L":")
            end
            WindowSetShowing("CharacterSelectFeatureWindow"..iIndex, bShow)
        else
            WindowSetShowing("CharacterSelectFeatureWindow"..iIndex, false)
        end
    end

    --DEBUG(L"  iNumFeatures = "..CharacterSelectWindow.iNumFeatures)
    if (iNumFeatures > 0)
    then
        -- anchor the random features button to the bottom visible button
        WindowClearAnchors( "CharacterSelectRandomFeatures" )
        WindowAddAnchor( "CharacterSelectRandomFeatures", "bottomright", "CharacterSelectFeatureWindow"..math.min(iNumFeatures, MAX_FEATURES).."PrevButton", "top", 0, 10 )
        WindowSetShowing("CharacterSelectRandomFeatures", bShow)
    else
        WindowSetShowing("CharacterSelectRandomFeatures", false)
    end
    
    -- Random name button
    WindowSetShowing("CharacterSelectRandomName", bShow)
end

function CharacterSelectWindow.RefreshFeatureLabels(bShow)
    iNumFeatures = CharacterSelectWindow.iNumFeatures

    for iIndex = 1, MAX_FEATURES
    do
        if (iIndex < iNumFeatures+1)
        then
            if ((CharacterSelectWindow.iRaceChoice > 0) and (CharacterSelectWindow.iCareerChoice > 0))
            then
                LabelSetText("CharacterSelectFeatureWindow"..iIndex.."FeatureLabel", CharacterSelectWindow.GetFeatureLabel(iIndex))
            else
                LabelSetText("CharacterSelectFeatureWindow"..iIndex.."FeatureLabel", L"Feature "..iIndex..L":")
            end
            WindowSetShowing("CharacterSelectFeatureWindow"..iIndex, bShow)
        else
            WindowSetShowing("CharacterSelectFeatureWindow"..iIndex, false)
        end
    end

    if ((iNumFeatures > 0) and (iNumFeatures <= MAX_FEATURES))
    then
        -- anchor the random features button to the bottom visible button
        WindowClearAnchors( "CharacterSelectRandomFeatures" )
        WindowAddAnchor( "CharacterSelectRandomFeatures", "bottomright", "CharacterSelectFeatureWindow"..iNumFeatures.."PrevButton", "top", 0, 10 )
        WindowSetShowing("CharacterSelectRandomFeatures", bShow)
    else
        WindowSetShowing("CharacterSelectRandomFeatures", false)
    end
end


function CharacterSelectWindow.RandomFeatures()
    BroadcastEvent( SystemData.Events.PREGAME_RANDOM_FEATURES )
end

function CharacterSelectWindow.ZoomIn()
    CharacterSelectWindow.ChangeState(STATE_CHARACTER_CREATE_FEATURE_IN)
end

function CharacterSelectWindow.ZoomOut()
    CharacterSelectWindow.ChangeState(STATE_CHARACTER_CREATE_FEATURE_OUT)
end

function CharacterSelectWindow.UpdateName( )
    if CharacterSelectWindow.iState ~= STATE_CHARACTER_CREATE_FEATURE_IN and CharacterSelectWindow.iState ~= STATE_CHARACTER_CREATE_FEATURE_OUT then
        return
    end
    
    if ( CharacterSelectNameEdit.Text ~= L"" ) then
        -- If the name has changed, ensure only the first letter is capitalized.
        if( GameData.Account.CharacterCreation.Name ~= CharacterSelectNameEdit.Text ) then
            local firstChar = wstring.upper( wstring.sub( CharacterSelectNameEdit.Text, 1, 1 ) )
            local remaining = L""
            if( wstring.len(CharacterSelectNameEdit.Text) > 1 ) then
                remaining = wstring.lower( wstring.sub( CharacterSelectNameEdit.Text, 2, 14 ) )
            end
            GameData.Account.CharacterCreation.Name = firstChar..remaining
            TextEditBoxSetText("CharacterSelectNameEdit", GameData.Account.CharacterCreation.Name ) 
        end
    end
end

function CharacterSelectWindow.SelectGender()
    if (ButtonGetDisabledFlag( SystemData.ActiveWindow.name ) == true)
    then
        return
    end
    CharacterSelectWindow.OnSelectGender( WindowGetId(SystemData.ActiveWindow.name) )
end

function CharacterSelectWindow.OnSelectGender( gender )
    --DEBUG(L"gender change: gender = "..gender)
    CharacterSelectWindow.iGender = gender
    GameData.Account.CharacterCreation.Gender = gender
    BroadcastEvent( SystemData.Events.UPDATE_CREATION_CHARACTER )
end

function CharacterSelectWindow.ForceUpdateState( eState )
    if (eState ~= nil)
    then
        --DEBUG(L"CharacterSelectWindow.ForceUpdateState eState = "..eState)
        --DEBUG(L"CharacterSelectWindow.ForceUpdateState CharacterSelectWindow.iState = "..CharacterSelectWindow.iState)
        if eState == CharacterSelectWindow.iState
        then
            return
        end

        if eState == STATE_CHARACTER_SELECT then            -- Normal Character Select
            if CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_FEATURE_IN or CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_FEATURE_OUT then
                GameData.Account.CharacterCreation.Name = L""
                TextEditBoxSetText("CharacterSelectNameEdit", GameData.Account.CharacterCreation.Name )
            end
            CharacterSelectWindow.ShowCharacterCreateArmy(false)
            CharacterSelectWindow.ShowCharacterCreateCareer(false)
            CharacterSelectWindow.ShowCharacterCreateFeature(false)
            CharacterSelectWindow.ShowCharacterSelect(true)
            CharacterSelectWindow.UpdateTitle(L"")
            CharacterSelectWindow.UpdateSubTitle(L"")
        elseif eState == STATE_CHARACTER_CREATE_ARMY then		-- Character Create - Army select
            CharacterSelectWindow.ShowCharacterSelect(false)
            CharacterSelectWindow.ShowCharacterCreateCareer(false)
            CharacterSelectWindow.ShowCharacterCreateFeature(false)
            CharacterSelectWindow.ShowCharacterCreateArmy(true)
            CharacterSelectWindow.UpdateTitle(GetPregameString( StringTables.Pregame.LABEL_CHOOSE_RACE ))
            CharacterSelectWindow.UpdateSubTitle(L"")
        elseif eState == STATE_CHARACTER_CREATE_CAREER then		-- Character Create - Career select
            CharacterSelectWindow.ShowCharacterSelect(false)
            CharacterSelectWindow.ShowCharacterCreateArmy(false)
            CharacterSelectWindow.ShowCharacterCreateFeature(false)
            CharacterSelectWindow.ShowCharacterCreateCareer(true)
            CharacterSelectWindow.UpdateTitle(GetPregameString( StringTables.Pregame.LABEL_CHOOSE_CAREER ))
            CharacterSelectWindow.UpdateSubTitle(L"")
            -- each time we go to the choose career state we will disable the create button
            -- this takes care of each direction since you can only change careers from this state
            CharacterSelectWindow.EnableCreateButton(false)
        elseif eState == STATE_CHARACTER_CREATE_FEATURE_IN or eState == STATE_CHARACTER_CREATE_FEATURE_OUT then		-- Character Create - Feature select
            CharacterSelectWindow.ShowCharacterSelect(false)
            CharacterSelectWindow.ShowCharacterCreateArmy(false)
            CharacterSelectWindow.ShowCharacterCreateCareer(false)
            CharacterSelectWindow.ShowCharacterCreateFeature(true)
            CharacterSelectWindow.UpdateTitle(GetPregameString( StringTables.Pregame.LABEL_CUSTOMIZE_YOUR_CHARACTER ))
            CharacterSelectWindow.UpdateSubTitle(L"")
        end
        CharacterSelectWindow.iState = eState
        GameData.Account.SelectedCharacterCurrentState = eState
        CharacterSelectWindow.UpdateInfoBoxes()
    end
end

function CharacterSelectWindow.OnQueueUpdated( waitSeconds, queuePos, queueSize )

    WindowSetShowing("QueueStatusWindow", true)

    CharacterSelectWindow.iQueueTime = waitSeconds
    CharacterSelectWindow.iQueuePos = queuePos
    CharacterSelectWindow.iQueueSize = queueSize
    CharacterSelectWindow.iLastUpdate = 0

    CharacterSelectWindow.UpdateQueueStatus()
end

function CharacterSelectWindow.UpdateQueueStatus()

    local text = GetPregameStringFormat( StringTables.Pregame.TEXT_REALM_FULL_QUEUE, { CharacterSelectWindow.iQueuePos, CharacterSelectWindow.iQueueSize, CharacterSelectWindow.GetTimeRemainingString() } )
    
    LabelSetText("QueueStatusWindowText", text)
    
    if( CharacterSelectWindow.iQueueTime == 0 )
    then
        CharacterSelectWindow.ResetPlayButton() 
    else
        -- Disable the play button until the player selects annother character
        ButtonSetDisabledFlag("CharacterSelectPlay", false )
    end

end

function CharacterSelectWindow.CharacterSelectionUpdated(iNewCharacterSelection)
    --DEBUG(L"iNewRace = "..iNewCharacterSelection)
    CharacterSelectWindow.iCharacterSelection = iNewCharacterSelection
    --DEBUG(L"CharacterSelectWindow.iCharacterSelection = "..CharacterSelectWindow.iCharacterSelection)
    if CharacterSelectWindow.bFirstCharUpdate then
        CharacterSelectWindow.bFirstCharUpdate = false
        if CharacterSelectWindow.iCharacterSelection == -1 then
            CharacterSelectWindow.NewChar()
        else
            CharacterSelectWindow.ChangeState(STATE_CHARACTER_SELECT)
        end
    else
        if iNewCharacterSelection == -1 then
            CharacterSelectWindow.NewChar()
        end
    end

    CharacterSelectWindow.ResetPlayButton()
end

function CharacterSelectWindow.RaceUpdated(iNewRace)
    --DEBUG(L"iNewRace = "..iNewRace)
    CharacterSelectWindow.iRaceChoice = iNewRace + 1
    CharacterSelectWindow.iCareerChoice = -1
end

function CharacterSelectWindow.CareerUpdated(iNewCareer)
    --DEBUG(L"iNewCareer = "..iNewCareer)
    if -1 == iNewCareer then -- so I don't have to go back to all of the -1 references and change them to 0
        CharacterSelectWindow.iCareerChoice = iNewCareer
    else
        CharacterSelectWindow.iCareerChoice = iNewCareer + 1
    end
    CharacterSelectWindow.UpdateCharacterTemplatesList()
    CharacterSelectWindow.ShowCharacterCreateCareer(true)
    -- each time we choose a career we will disable the create button
    CharacterSelectWindow.EnableCreateButton(false)
end

function CharacterSelectWindow.RealmUpdated(iNewRealm)
    --DEBUG(L"iNewRealm = "..iNewRealm)
    CharacterSelectWindow.iRealm = iNewRealm + 1
end

function CharacterSelectWindow.GenderUpdated(iNewGender)
    --DEBUG(L"iNewGender = "..iNewGender)
    CharacterSelectWindow.iGender = iNewGender
    GameData.Account.CharacterCreation.Gender = iNewGender
end

function CharacterSelectWindow.MouseOverUpdated(iNewMouseOver)
    --DEBUG(L"iNewMouseOver = "..iNewMouseOver)
    CharacterSelectWindow.iMouseOver = iNewMouseOver
    CharacterSelectWindow.UpdateInfoBoxes()
end

function CharacterSelectWindow.RealmOverUpdated(iNewRealmOver)
    --DEBUG(L"iNewRealmOver = "..iNewRealmOver)
    CharacterSelectWindow.iRealmOver = iNewRealmOver
    CharacterSelectWindow.UpdateInfoBoxes()
end

function CharacterSelectWindow.NumFeaturesUpdated(iNumFeatures)
    --DEBUG(L"iNumFeatures = "..iNumFeatures)
    CharacterSelectWindow.iNumFeatures = iNumFeatures
    if ((CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_FEATURE_IN) or (CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_FEATURE_OUT)) then
        CharacterSelectWindow.RefreshFeatureLabels(true)
    end
end

function CharacterSelectWindow.InitializeFeatureStrings( )

    CharacterSelectWindow.BuildCharacterDataList()
    
    featureStrings[ RACE_DWARF ] = {}
    featureStrings[ RACE_DWARF ].Career = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_IRON_BREAKER] = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_SLAYER] = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_ENGINEER] = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_RUNE_PRIEST] = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_IRON_BREAKER].FeatureNameMale = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_SLAYER].FeatureNameMale = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_ENGINEER].FeatureNameMale = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_RUNE_PRIEST].FeatureNameMale = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_IRON_BREAKER].FeatureNameFemale = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_SLAYER].FeatureNameFemale = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_ENGINEER].FeatureNameFemale = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_RUNE_PRIEST].FeatureNameFemale = {}
    featureStrings[ RACE_DWARF ].Career[CAREER_IRON_BREAKER].LastIndexMale = 0
    featureStrings[ RACE_DWARF ].Career[CAREER_SLAYER].LastIndexMale = 0
    featureStrings[ RACE_DWARF ].Career[CAREER_ENGINEER].LastIndexMale = 0
    featureStrings[ RACE_DWARF ].Career[CAREER_RUNE_PRIEST].LastIndexMale = 0
    featureStrings[ RACE_DWARF ].Career[CAREER_IRON_BREAKER].LastIndexFemale = 0
    featureStrings[ RACE_DWARF ].Career[CAREER_SLAYER].LastIndexFemale = 0
    featureStrings[ RACE_DWARF ].Career[CAREER_ENGINEER].LastIndexFemale = 0
    featureStrings[ RACE_DWARF ].Career[CAREER_RUNE_PRIEST].LastIndexFemale = 0

    featureStrings[ RACE_EMPIRE ] = {}
    featureStrings[ RACE_EMPIRE ].Career = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_BRIGHT_WIZARD] = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WARRIOR_PRIEST] = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_KNIGHT] = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WITCH_HUNTER] = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_BRIGHT_WIZARD].FeatureNameMale = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WARRIOR_PRIEST].FeatureNameMale = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_KNIGHT].FeatureNameMale = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WITCH_HUNTER].FeatureNameMale = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_BRIGHT_WIZARD].FeatureNameFemale = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WARRIOR_PRIEST].FeatureNameFemale = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_KNIGHT].FeatureNameFemale = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WITCH_HUNTER].FeatureNameFemale = {}
    featureStrings[ RACE_EMPIRE ].Career[CAREER_BRIGHT_WIZARD].LastIndexMale = 0
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WARRIOR_PRIEST].LastIndexMale = 0
    featureStrings[ RACE_EMPIRE ].Career[CAREER_KNIGHT].LastIndexMale = 0
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WITCH_HUNTER].LastIndexMale = 0
    featureStrings[ RACE_EMPIRE ].Career[CAREER_BRIGHT_WIZARD].LastIndexFemale = 0
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WARRIOR_PRIEST].LastIndexFemale = 0
    featureStrings[ RACE_EMPIRE ].Career[CAREER_KNIGHT].LastIndexFemale = 0
    featureStrings[ RACE_EMPIRE ].Career[CAREER_WITCH_HUNTER].LastIndexFemale = 0

    featureStrings[ RACE_HIGH_ELF ] = {}
    featureStrings[ RACE_HIGH_ELF ].Career = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SWORDMASTER] = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SHADOW_WARRIOR] = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_WHITE_LION] = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_ARCHMAGE] = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SWORDMASTER].FeatureNameMale = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SHADOW_WARRIOR].FeatureNameMale = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_WHITE_LION].FeatureNameMale = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_ARCHMAGE].FeatureNameMale = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SWORDMASTER].FeatureNameFemale = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SHADOW_WARRIOR].FeatureNameFemale = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_WHITE_LION].FeatureNameFemale = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_ARCHMAGE].FeatureNameFemale = {}
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SWORDMASTER].LastIndexMale = 0
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SHADOW_WARRIOR].LastIndexMale = 0
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_WHITE_LION].LastIndexMale = 0
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_ARCHMAGE].LastIndexMale = 0
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SWORDMASTER].LastIndexFemale = 0
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_SHADOW_WARRIOR].LastIndexFemale = 0
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_WHITE_LION].LastIndexFemale = 0
    featureStrings[ RACE_HIGH_ELF ].Career[CAREER_ARCHMAGE].LastIndexFemale = 0

    featureStrings[ RACE_ORC ] = {}
    featureStrings[ RACE_ORC ].Career = {}
    featureStrings[ RACE_ORC ].Career[CAREER_BLACK_ORC] = {}
    featureStrings[ RACE_ORC ].Career[CAREER_CHOPPA] = {}
    featureStrings[ RACE_ORC ].Career[CAREER_BLACK_ORC].FeatureNameMale = {}
    featureStrings[ RACE_ORC ].Career[CAREER_CHOPPA].FeatureNameMale = {}
    featureStrings[ RACE_ORC ].Career[CAREER_BLACK_ORC].LastIndexMale = 0
    featureStrings[ RACE_ORC ].Career[CAREER_CHOPPA].LastIndexMale = 0

    featureStrings[ RACE_GOBLIN ] = {}
    featureStrings[ RACE_GOBLIN ].Career = {}
    featureStrings[ RACE_GOBLIN ].Career[CAREER_SHAMAN] = {}
    featureStrings[ RACE_GOBLIN ].Career[CAREER_SQUIG_HERDER] = {}
    featureStrings[ RACE_GOBLIN ].Career[CAREER_SHAMAN].FeatureNameMale = {}
    featureStrings[ RACE_GOBLIN ].Career[CAREER_SQUIG_HERDER].FeatureNameMale = {}
    featureStrings[ RACE_GOBLIN ].Career[CAREER_SHAMAN].LastIndexMale = 0
    featureStrings[ RACE_GOBLIN ].Career[CAREER_SQUIG_HERDER].LastIndexMale = 0

    featureStrings[ RACE_CHAOS_1 ] = {}
    featureStrings[ RACE_CHAOS_1 ].Career = {}
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_ZEALOT] = {}
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_MAGUS] = {}
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_ZEALOT].FeatureNameMale = {}
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_MAGUS].FeatureNameMale = {}
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_ZEALOT].FeatureNameFemale = {}
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_MAGUS].FeatureNameFemale = {}
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_ZEALOT].LastIndexMale = 0
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_MAGUS].LastIndexMale = 0
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_ZEALOT].LastIndexFemale = 0
    featureStrings[ RACE_CHAOS_1 ].Career[CAREER_MAGUS].LastIndexFemale = 0

    featureStrings[ RACE_CHAOS_2 ] = {}
    featureStrings[ RACE_CHAOS_2 ].Career = {}
    featureStrings[ RACE_CHAOS_2 ].Career[CAREER_CHOSEN] = {}
    featureStrings[ RACE_CHAOS_2 ].Career[CAREER_MARAUDER] = {}
    featureStrings[ RACE_CHAOS_2 ].Career[CAREER_CHOSEN].FeatureNameMale = {}
    featureStrings[ RACE_CHAOS_2 ].Career[CAREER_MARAUDER].FeatureNameMale = {}
    featureStrings[ RACE_CHAOS_2 ].Career[CAREER_CHOSEN].LastIndexMale = 0
    featureStrings[ RACE_CHAOS_2 ].Career[CAREER_MARAUDER].LastIndexMale = 0
    featureStrings[ RACE_CHAOS_2 ].Career[CAREER_CHOSEN].LastIndexFemale = 0
    featureStrings[ RACE_CHAOS_2 ].Career[CAREER_MARAUDER].LastIndexFemale = 0

    featureStrings[ RACE_DARK_ELF ] = {}
    featureStrings[ RACE_DARK_ELF ].Career = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_WITCH_ELF] = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_BLACKGUARD] = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_DISCIPLE] = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_SORCERER] = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_WITCH_ELF].FeatureNameMale = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_BLACKGUARD].FeatureNameMale = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_DISCIPLE].FeatureNameMale = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_SORCERER].FeatureNameMale = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_WITCH_ELF].FeatureNameFemale = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_BLACKGUARD].FeatureNameFemale = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_DISCIPLE].FeatureNameFemale = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_SORCERER].FeatureNameFemale = {}
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_WITCH_ELF].LastIndexMale = 0
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_BLACKGUARD].LastIndexMale = 0
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_DISCIPLE].LastIndexMale = 0
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_SORCERER].LastIndexMale = 0
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_WITCH_ELF].LastIndexFemale = 0
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_BLACKGUARD].LastIndexFemale = 0
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_DISCIPLE].LastIndexFemale = 0
    featureStrings[ RACE_DARK_ELF ].Career[CAREER_SORCERER].LastIndexFemale = 0

    local numEntries = #PregameFeatureList
    for curSelection = 1, numEntries  do
        if (PregameFeatureList == nil) or (PregameFeatureList[curSelection] == nil) then
            continue
        end
        
        if PregameFeatureList[curSelection].FEATURE_RACE == "RACE_DWARF" then
            CharacterSelectWindow.SetFeatureWithRace( curSelection, RACE_DWARF )
        elseif PregameFeatureList[curSelection].FEATURE_RACE == "RACE_EMPIRE" then
            CharacterSelectWindow.SetFeatureWithRace( curSelection, RACE_EMPIRE )
        elseif PregameFeatureList[curSelection].FEATURE_RACE == "RACE_ELVES" then
            CharacterSelectWindow.SetFeatureWithRace( curSelection, RACE_HIGH_ELF )
        elseif PregameFeatureList[curSelection].FEATURE_RACE == "RACE_ORC" then
            CharacterSelectWindow.SetFeatureWithRace( curSelection, RACE_ORC )
        elseif PregameFeatureList[curSelection].FEATURE_RACE == "RACE_GOBLIN" then
            CharacterSelectWindow.SetFeatureWithRace( curSelection, RACE_GOBLIN )
        elseif PregameFeatureList[curSelection].FEATURE_RACE == "RACE_CHAOS" then
            if (PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_ZEALOT" or 
                    PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_MAGUS") then
                CharacterSelectWindow.SetFeatureWithRace( curSelection, RACE_CHAOS_1 )
            else
                CharacterSelectWindow.SetFeatureWithRace( curSelection, RACE_CHAOS_2 )
            end
        elseif PregameFeatureList[curSelection].FEATURE_RACE == "RACE_DARK_ELVES" then
            CharacterSelectWindow.SetFeatureWithRace( curSelection, RACE_DARK_ELF )
        end
    end
end

function CharacterSelectWindow.SetFeatureWithRace( curSelection, race )
    if PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_SLAYER" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_SLAYER )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_IRON_BREAKER" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_IRON_BREAKER )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_ENGINEER" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_ENGINEER )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_RUNE_PRIEST" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_RUNE_PRIEST )

    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_BRIGHT_WIZARD" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_BRIGHT_WIZARD )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_WARRIOR_PRIEST" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_WARRIOR_PRIEST )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_KNIGHT" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_KNIGHT )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_WITCH_HUNTER" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_WITCH_HUNTER )

    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_SWORDMASTER" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_SWORDMASTER )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_SHADOW_WARRIOR" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_SHADOW_WARRIOR )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_WHITE_LION" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_WHITE_LION )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_ARCHMAGE" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_ARCHMAGE )

    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_BLACK_ORC" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_BLACK_ORC )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_CHOPPA" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_CHOPPA )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_SHAMAN" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_SHAMAN )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_SQUIG_HERDER" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_SQUIG_HERDER )

    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_ZEALOT" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_ZEALOT )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_CHOSEN" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_CHOSEN )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_MAGUS" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_MAGUS )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_MARAUDER" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_MARAUDER )

    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_WITCH_ELF" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_WITCH_ELF )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_BLACKGUARD" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_BLACKGUARD )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_DISCIPLE" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_DISCIPLE )
    elseif PregameFeatureList[curSelection].FEATURE_CAREER == "CAREER_SORCERER" then
        CharacterSelectWindow.SetFeatureDataString( curSelection, race, CAREER_SORCERER )
    end

end

function CharacterSelectWindow.SetFeatureDataString( curSelection, race, career )
    local curIndex
    if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
        curIndex = featureStrings[ race ].Career[career].LastIndexMale+1
        featureStrings[ race ].Career[career].LastIndexMale = curIndex
    elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
        curIndex = featureStrings[ race ].Career[career].LastIndexFemale+1
        featureStrings[ race ].Career[career].LastIndexFemale = curIndex
    end

    if PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_HAIR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_HAIR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_HAIR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_HAIR_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_HAIR_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_HAIR_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_BEARD" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_BEARD )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_BEARD )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_BEARD_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_BEARD_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_BEARD_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_FACE" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_FACE )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_FACE )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_SKIN_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_SKIN_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_SKIN_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_TEETH" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TEETH )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TEETH )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_EARS" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_EARS )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_EARS )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_EYE_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_EYE_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_EYE_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_TEETH_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TEETH_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TEETH_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_TUSK" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TUSK )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TUSK )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_TUSK CAP_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TUSKCAP_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TUSKCAP_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_METAL_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_METAL_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_METAL_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_JEWELRY" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_JEWELRY )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_JEWELRY )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_TATOO" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TATOO )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TATOO )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_TAT_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TATOO_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TATOO_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_CIRCLET" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_CIRCLET )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_CIRCLET )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_CIRCLET_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_CIRCLET_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_CIRCLET_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_RANDOM" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_RANDOM )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_RANDOM )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_TEETH_METAL_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TEETH_METAL_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TEETH_METAL_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_ACCESSORY" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_ACCESSORY )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_ACCESSORY )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_ACCESSORY_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_ACCESSORY_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_ACCESSORY_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_TIARA_COLOR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TIARA_COLOR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_TIARA_COLOR )
        end
    elseif PregameFeatureList[curSelection].FEATURE_LABEL == "LABEL_FEATURE_SCAR" then
        if PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_MALE" then
            featureStrings[ race ].Career[career].FeatureNameMale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_SCAR )
        elseif PregameFeatureList[curSelection].FEATURE_GENDER == "GENDER_FEMALE" then
            featureStrings[ race ].Career[career].FeatureNameFemale[curIndex] = GetPregameString( StringTables.Pregame.LABEL_FEATURE_SCAR )
        end
    end
end

function CharacterSelectWindow.BuildCharacterDataList()
    BuildTableFromCSV("data\\gamedata\\pregame_features.csv", "PregameFeatureList")
end

function CharacterSelectWindow.UpdateTitle(szLabel)
    --DEBUG(L"szLabel = "..szLabel)
    LabelSetText("CharacterSelectTitleLabel", szLabel)
end

function CharacterSelectWindow.UpdateSubTitle(szLabel)
    --DEBUG(L"szLabel = "..szLabel)
    LabelSetText("CharacterSelectTitleSubLabel", szLabel)
end

function CharacterSelectWindow.UpdateInfoBoxes()
    -- Character Create - Army select
    if CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_ARMY
    then
        wszLeftTitle        = GetPregameString( StringTables.Pregame.LABEL_REALM_ORDER )
        wszLeftSecondTitleLeft  = GetPregameString( StringTables.Pregame.LABEL_ARMYS_DWARF )
        wszLeftSecondTitleMiddle  = GetPregameString( StringTables.Pregame.LABEL_ARMYS_EMPIRE )
        wszLeftSecondTitleRight  = GetPregameString( StringTables.Pregame.LABEL_ARMYS_HIGH_ELF )
        wszLeftLabel        = GetPregameString( StringTables.Pregame.LABEL_ORDER_DESCRIPTION )
        wszRightTitle       = GetPregameString( StringTables.Pregame.LABEL_REALM_DESTRUCTION )
        wszRightSecondTitleLeft = GetPregameString( StringTables.Pregame.LABEL_ARMYS_DARK_ELF )
        wszRightSecondTitleMiddle = GetPregameString( StringTables.Pregame.LABEL_ARMYS_CHAOS )
        wszRightSecondTitleRight = GetPregameString( StringTables.Pregame.LABEL_ARMYS_GREENSKIN )
        wszRightLabel       = GetPregameString( StringTables.Pregame.LABEL_DESTRUCTION_DESCRIPTION )
        -- initailize the population bonus text to the empty string and hide the icons
        wszRightPopBonus    = L""
        wszLeftPopBonus     = L""
        WindowSetShowing("CharacterSelectInfoBoxLeftIconBase", false)
        WindowSetShowing("CharacterSelectInfoBoxRightIconBase", false)

        -- get the realm bonuses that the server select screen set for us
        local iOrderBonus, iDestructionBonus = PregameGetServerRealmBonuses()
        -- if there is an order bonus we will set the label text and show the icon
        if iOrderBonus ~= 0
        then
            realmText = GetPregameString( StringTables.Pregame.LABEL_ORDER )
            wszLeftPopBonus = GetStringFormatFromTable( "Pregame", StringTables.Pregame.LABEL_POPULATION_BONUS, { realmText } )
            WindowSetShowing("CharacterSelectInfoBoxLeftIconBase", true)
        end
        -- if there is a destruction bonus we will set the label text and show the icon
        if iDestructionBonus ~= 0
        then
            realmText = GetPregameString( StringTables.Pregame.LABEL_CHAOS )
            wszRightPopBonus = GetStringFormatFromTable( "Pregame", StringTables.Pregame.LABEL_POPULATION_BONUS, { realmText } )
            WindowSetShowing("CharacterSelectInfoBoxRightIconBase", true)
        end

        if 0 == CharacterSelectWindow.iRealmOver
        then
            if (0 <= CharacterSelectWindow.iMouseOver) and (2 >= CharacterSelectWindow.iMouseOver)
            then
                wszLeftLabel = CharacterDataOrderCareers[CharacterSelectWindow.iMouseOver+1].Desc
            end
        else
            if (0 <= CharacterSelectWindow.iMouseOver) and (2 >= CharacterSelectWindow.iMouseOver)
            then
                wszRightLabel = CharacterDataDestructionCareers[CharacterSelectWindow.iMouseOver+1].Desc
            end
        end

        CharacterSelectWindow.ColorizeInfoBoxes(CharacterSelectWindow.iRealmOver)

        -- get the realm limitation for the player
        local realmLimit = PregameGetRealmLimit( )
        --DEBUG(L"RealmLimit = "..realmLimit)
        -- if the realm limitation is order only we need to let the player know what happened to the
        -- destruction option
        if REALM_LIMIT_ORDER_ONLY == realmLimit
        then
            wszRightTitle = GetPregameString( StringTables.Pregame.LABEL_DESTRUCTION_NOT_ELIGIBLE )
            wszRightSecondTitleLeft = L""
            wszRightSecondTitleMiddle = L""
            wszRightSecondTitleRight = L""
            wszRightLabel = GetPregameString( StringTables.Pregame.LABEL_DESTRUCTION_NOT_ELIGIBLE_DESCRIPTION )
        -- if the realm limitation is destruction only we need to let the player know what happened to the
        -- order option
        elseif REALM_LIMIT_DESTRUCTION_ONLY == realmLimit
        then
            wszLeftTitle = GetPregameString( StringTables.Pregame.LABEL_ORDER_NOT_ELIGIBLE )
            wszLeftSecondTitleLeft = L""
            wszLeftSecondTitleMiddle = L""
            wszLeftSecondTitleRight = L""
            wszLeftLabel = GetPregameString( StringTables.Pregame.LABEL_ORDER_NOT_ELIGIBLE_DESCRIPTION )
        end

        -- if there is a pre-selected server limitation we will hide the un-shown side's info box
        local preSelectedServerRealm = PregameGetPreSelectedServerRealm( )
        if REALM_LIMIT_ORDER_ONLY == preSelectedServerRealm
        then
            WindowSetShowing("CharacterSelectInfoBoxRight", false)
        elseif REALM_LIMIT_DESTRUCTION_ONLY == preSelectedServerRealm
        then
            WindowSetShowing("CharacterSelectInfoBoxLeft", false)
        end


        LabelSetText("CharacterSelectInfoBoxLeftLabelTitle",        wszLeftTitle)
        LabelSetText("CharacterSelectInfoBoxLeftLabelSecondTitleLeft",  wszLeftSecondTitleLeft)
        LabelSetText("CharacterSelectInfoBoxLeftLabelSecondTitleMiddle",  wszLeftSecondTitleMiddle)
        LabelSetText("CharacterSelectInfoBoxLeftLabelSecondTitleRight",  wszLeftSecondTitleRight)
        LabelSetText("CharacterSelectInfoBoxLeftLabel",             wszLeftLabel)
        LabelSetText("CharacterSelectInfoBoxRightLabelTitle",       wszRightTitle)
        LabelSetText("CharacterSelectInfoBoxRightLabelSecondTitleLeft", wszRightSecondTitleLeft)
        LabelSetText("CharacterSelectInfoBoxRightLabelSecondTitleMiddle", wszRightSecondTitleMiddle)
        LabelSetText("CharacterSelectInfoBoxRightLabelSecondTitleRight", wszRightSecondTitleRight)
        LabelSetText("CharacterSelectInfoBoxRightLabel",            wszRightLabel)
        LabelSetText("CharacterSelectInfoBoxLeftPopBonusLabel",            wszLeftPopBonus)
        LabelSetText("CharacterSelectInfoBoxRightPopBonusLabel",            wszRightPopBonus)

    -- Character Create - Career select
    elseif CharacterSelectWindow.iState == STATE_CHARACTER_CREATE_CAREER
    then
        -- the default text should vary based on realm
        if 1 == CharacterSelectWindow.iRealm then
            wszLabelTitle = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Name
            wszLabelDesc = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Desc
        else
            wszLabelTitle = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Name
            wszLabelDesc = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Desc
        end
        if (1 <= CharacterSelectWindow.iCareerChoice) and (4 >= CharacterSelectWindow.iCareerChoice) then
            if 1 == CharacterSelectWindow.iRealm then
                if 1 == CharacterSelectWindow.iGender then -- male
                    wszLabelTitle = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].MaleName
                else
                    wszLabelTitle = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].FemaleName
                end
                wszLabelDesc = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].Desc
            else
                if 1 == CharacterSelectWindow.iGender then -- male
                    wszLabelTitle = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].MaleName
                else
                    wszLabelTitle = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].FemaleName
                end
                wszLabelDesc = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].Desc
            end
        end
        if (0 <= CharacterSelectWindow.iMouseOver) and (3 >= CharacterSelectWindow.iMouseOver) then
            if 1 == CharacterSelectWindow.iRealm then
                if 1 == CharacterSelectWindow.iGender then -- male
                    wszLabelTitle = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iMouseOver+1].MaleName
                else
                    wszLabelTitle = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iMouseOver+1].FemaleName
                end
                wszLabelDesc = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iMouseOver+1].Desc
            else
                if 1 == CharacterSelectWindow.iGender then -- male
                    wszLabelTitle = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iMouseOver+1].MaleName
                else
                    wszLabelTitle = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iMouseOver+1].FemaleName
                end
                wszLabelDesc = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iMouseOver+1].Desc
            end
        end
        LabelSetText("CharacterSelectInfoBox2RightLabelTitle", wszLabelTitle)
        LabelSetText("CharacterSelectInfoBox2RightLabel", wszLabelDesc)
    end

end

function CharacterSelectWindow.ColorizeInfoBoxes(selectedSide)

    LabelSetTextColor("CharacterSelectInfoBox2RightLabelTitle",      DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
    LabelSetTextColor("CharacterSelectInfoBoxLeftPopBonusLabel",      DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
    LabelSetTextColor("CharacterSelectInfoBoxRightPopBonusLabel", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)

    -- neither selected
    if (selectedSide == -1) then
        LabelSetTextColor("CharacterSelectInfoBoxLeftLabelTitle",       DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
        LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleLeft", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
        LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleMiddle", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
        LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleRight", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
        LabelSetTextColor("CharacterSelectInfoBoxLeftLabel",            DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)

        LabelSetTextColor("CharacterSelectInfoBoxRightLabelTitle",      DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
        LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleLeft", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
        LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleMiddle", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
        LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleRight", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
        LabelSetTextColor("CharacterSelectInfoBoxRightLabel",           DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
    -- order
    else
        if 0 == CharacterSelectWindow.iRealmOver then
            LabelSetTextColor("CharacterSelectInfoBoxLeftLabelTitle",       DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            LabelSetTextColor("CharacterSelectInfoBoxLeftLabel",            DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            if (0 == CharacterSelectWindow.iMouseOver) then
                LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleLeft", DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            else
                LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleLeft", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
            end
            if (1 == CharacterSelectWindow.iMouseOver) then
                LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleMiddle", DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            else
                LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleMiddle", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
            end
            if (2 == CharacterSelectWindow.iMouseOver) then
                LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleRight", DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            else
                LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleRight", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
            end

            LabelSetTextColor("CharacterSelectInfoBoxRightLabelTitle",      DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
            LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleLeft", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
            LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleMiddle", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
            LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleRight", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
            LabelSetTextColor("CharacterSelectInfoBoxRightLabel",           DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
        else
            LabelSetTextColor("CharacterSelectInfoBoxLeftLabelTitle",       DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
            LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleLeft", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
            LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleMiddle", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
            LabelSetTextColor("CharacterSelectInfoBoxLeftLabelSecondTitleRight", DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)
            LabelSetTextColor("CharacterSelectInfoBoxLeftLabel",            DefaultColor.YELLOW.r, DefaultColor.YELLOW.g, DefaultColor.YELLOW.b)

            LabelSetTextColor("CharacterSelectInfoBoxRightLabelTitle",      DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            LabelSetTextColor("CharacterSelectInfoBoxRightLabel",           DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)

            -- greenskin is on the right side of the screen but is mouse over index 0
            -- dark elf is on the left side of the destruction races but is mouse over index 2
            -- hence the swap of the comparisons here.
            if (2 == CharacterSelectWindow.iMouseOver) then
                LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleLeft", DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            else
                LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleLeft", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
            end
            if (1 == CharacterSelectWindow.iMouseOver) then
                LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleMiddle", DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            else
                LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleMiddle", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
            end
            if (0 == CharacterSelectWindow.iMouseOver) then
                LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleRight", DefaultColor.WHITE.r, DefaultColor.WHITE.g, DefaultColor.WHITE.b)
            else
                LabelSetTextColor("CharacterSelectInfoBoxRightLabelSecondTitleRight", DefaultColor.PREGAME_RED.r, DefaultColor.PREGAME_RED.g, DefaultColor.PREGAME_RED.b)
            end
        end
    end
end

function CharacterSelectWindow.UpdateCharacterTemplatesList()
    --DEBUG(L"UpdateCharacterTemplatesList")
    -- Clear ComboBox before populating to avoid duplicates
    ComboBoxClearMenuItems("CharacterSelectWindowTemplateCombo")
    -- reset must use template flag
    CharacterSelectWindow.bMustUseATemplate = false
    
    local careerID = -1
    -- figure out the current career's ID
    if (1 <= CharacterSelectWindow.iCareerChoice) and (4 >= CharacterSelectWindow.iCareerChoice) then
        if 1 == CharacterSelectWindow.iRealm then
            careerID = CharacterDataOrderCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].Id
        else
            careerID = CharacterDataDestructionCareers[CharacterSelectWindow.iRaceChoice].Careers[CharacterSelectWindow.iCareerChoice].Id
        end
    end

--    if(IsInternalBuild()) then
        ComboBoxAddMenuItem("CharacterSelectWindowTemplateCombo", GetPregameString( StringTables.Pregame.LABEL_NO_TEMPLATE ))
        if (GameData.Account.CharacterCreation.AvailableTemplates_Names ~= nil) then
            -- Add template options to the combobox
            for index, name in ipairs(GameData.Account.CharacterCreation.AvailableTemplates_Names) do

                if (GameData.Account.CharacterCreation.AvailableTemplates_Classes[index] == careerID) then
                    ComboBoxAddMenuItem("CharacterSelectWindowTemplateCombo", name)
                    -- since we have a template we will force the use of a template
                    CharacterSelectWindow.bMustUseATemplate = true
                end
            end
        end

        -- Reset selections
        ComboBoxSetSelectedMenuItem("CharacterSelectWindowTemplateCombo", 1)
--	end

end

-- OnSelectionChange Handler for the Templates ComboBox
function CharacterSelectWindow.OnFilterSelChanged( curSel )

    selectedTemplateItem = ComboBoxGetSelectedMenuItem("CharacterSelectWindowTemplateCombo")-1
    -- if we have a valid template item then we will set the lua variable
    if (selectedTemplateItem >= 1) then
        CharacterSelectWindow.bUseTemplate = true
        GameData.Account.CharacterCreation.Template = ComboBoxGetSelectedText("CharacterSelectWindowTemplateCombo")
        -- since we have a valid template we can go ahead and enable the character create button
        CharacterSelectWindow.EnableCreateButton(true)
    -- otherwise we will set the lua var to the empty string
    else
        CharacterSelectWindow.bUseTemplate = false
        GameData.Account.CharacterCreation.Template = L""
        -- since we don't have a valid template we will disable the character create button
        CharacterSelectWindow.EnableCreateButton(false)
    end
    
end

function CharacterSelectWindow.SetSelectedCharRace(selectedRace)
    GameData.Account.CharacterCreation.Race = selectedRace
    -- if this is an orc or goblin
    if (GameData.Account.CharacterCreation.Race == 2) then
        -- check if it is a goblin and if so change the race from orc to goblin
        if (GameData.Account.CharacterCreation.Career == 26) or (GameData.Account.CharacterCreation.Career == 27) then
            GameData.Account.CharacterCreation.Race = selectedRace + 1 -- set the race to a goblin
        end
    end
    --DEBUG(L"selectedRace = "..selectedRace)
    --DEBUG(L"GameData.Account.CharacterCreation.Race = "..GameData.Account.CharacterCreation.Race)
    --DEBUG(L"GameData.Account.CharacterCreation.Career = "..GameData.Account.CharacterCreation.Career)
end

function CharacterSelectWindow.EnableCreateButton(bEnable)
    -- only do enable / disable the create button if this is not an internal build
    -- we only want to bother with this if we are allowing public clients to use templates
    if (CharacterSelectWindow.AllowPublicTemplates() and (IsInternalBuild() == false))
    then
        if ((not CharacterSelectWindow.bMustUseATemplate) or bEnable) then
            ButtonSetDisabledFlag( "CharacterSelectCareerCreateChar", false )
        else
            ButtonSetDisabledFlag( "CharacterSelectCareerCreateChar", true )
        end
    end
end

function CharacterSelectWindow.ManageProgressWindow()
    if (DoesWindowExist("LoginProgressWindow")) then
        WindowSetShowing("LoginProgressWindow", false)
    end
end

function CharacterSelectWindow.GiveDeleteEditBoxFocus()
    WindowAssignFocus("DeleteConfirmationBoxEdit", true)
end

function CharacterSelectWindow.UpdateCharacterSelectRandomName()
    ButtonSetDisabledFlag( "CharacterSelectRandomName", false )
    TextEditBoxSetText("CharacterSelectNameEdit", GameData.Account.CharacterCreation.Name)
end

function CharacterSelectWindow.UpdateCharacterForcedRandomName()
    ButtonSetDisabledFlag( "ForcedRandomNameBoxRandom", false)
    LabelSetText("ForcedRandomNameBoxDisplay", GameData.Account.CharacterCreation.Name)
end

function CharacterSelectWindow.InitForcedRandomNameDialog()
    local promptLabel = GetPregameString( StringTables.Pregame.TEXT_FORCED_RENAME_CHARACTER )
    local randomLabel = GetPregameString( StringTables.Pregame.LABEL_BUTTON_RANDOM_NAME )
    local acceptLabel = GetPregameString( StringTables.Pregame.LABEL_BUTTON_FORCE_RENAME_ACCEPT )
  
    WindowSetShowing("ForcedRandomName", false)
    LabelSetText("ForcedRandomNameBoxLabelPrompt", promptLabel)
    ButtonSetText("ForcedRandomNameBoxRandom", randomLabel)
    ButtonSetText("ForcedRandomNameBoxAccept", acceptLabel)
end

function CharacterSelectWindow.ShowForcedNameSelectWindow()
    WindowSetShowing("ForcedRandomName", true)
    CharacterSelectWindow.BlockMouseOver(true)
    LabelSetText("ForcedRandomNameBoxDisplay", GameData.Account.CharacterCreation.Name)    
end

function CharacterSelectWindow.AcceptForcedRandomName()       
    if (DoesWindowExist("ForcedRandomName")) then
        WindowSetShowing("ForcedRandomName", false)
    end  

    ButtonSetDisabledFlag( "ForcedRandomNameBoxRandom", true)    
    ButtonSetPressedFlag("CharacterSelectPlay", true )
    ButtonSetDisabledFlag("CharacterSelectPlay", true )
    
    CharacterSelectWindow.BlockMouseOver(false)

    -- this message triggers makes them go to a play state
    BroadcastEvent( SystemData.Events.CHARACTER_PREGAME_FORCED_RANDOM_NAME_ACCEPT )
end

function CharacterSelectWindow.InitForcedRenameFailedWindow()
    local promptLabel = GetPregameString( StringTables.Pregame.TEXT_FORCED_RENAME_CHARACTER_FAILED )
    local acceptLabel = GetPregameString( StringTables.Pregame.LABEL_OKAY )
  
    WindowSetShowing("ForcedRenameFailedWindow", false)
    LabelSetText("ForcedRenameFailedWindowText", promptLabel)
    ButtonSetText("ForcedRenameFailedWindowOk", acceptLabel)
end

function CharacterSelectWindow.ShowForcedRenameFailedWindow()
    WindowSetShowing("ForcedRenameFailedWindowOk", true)
    CharacterSelectWindow.BlockMouseOver(true)
end

function CharacterSelectWindow.CloseFailedRename()
    if (DoesWindowExist("ForcedRenameFailedWindow")) then
        WindowSetShowing("ForcedRenameFailedWindow", false)
    end  
end


-- putting this in a function so that I can swap it out for a C call if it becomes necessary
function CharacterSelectWindow.AllowPublicTemplates()
    return CharacterSelectWindow.bAllowTemplatesInPublicBuilds
end

function CharacterSelectWindow.GetTimeRemainingString()
    if CharacterSelectWindow.iQueueTime < 60
    then
        return GetPregameString( StringTables.Pregame.LABEL_SMALL_TIMER  )
    elseif CharacterSelectWindow.iQueueTime == CharacterSelectWindow.iMaxQueueTime
    then
        return L""
    end

    return TimeUtils.FormatTime(CharacterSelectWindow.iQueueTime)
end

function CharacterSelectWindow.RefreshPlayerData()
    CharacterSelectWindow.trialPlayer, CharacterSelectWindow.buddiedPlayer = GetAccountData()
end

function CharacterSelectWindow.UpgradeTrial()
    EA_TrialAlertWindow.OnUpgradeWithOutClose()
end
